<?php

namespace App\Models;

use App\Exceptions\ApiException;
use App\Jobs\HandleRebate;
use App\Services\Base\HelpService;
use App\Services\GlobalConfigService;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;


/**
 * This is the model class for table "user_withdraws"
 *
 * @property string $id
 * @property string $uid 用户id
 * @property string $from_symbol 来源币
 * @property string $from_amount 来源数量
 * @property string $to_symbol 目标币
 * @property string $to_amount 目标数量
 * @property string $rate 汇率
 * @property string $from_address 转入地址
 * @property string $to_address 转出地址
 * @property string $status 状态 1提交 2成功 3失败
 * @property string $fee_symbol 手续费币
 * @property string $fee 手续费
 * @property string $remark 备注
 * @property string $executed_at 执行完成时间
 * @property string $executed_tx 执行哈希
 * @property string $real_amount 实际到账
 * @property string $created_at 创建时间
 * @property string $updated_at 更新时间
 * @property string $tx_status 链状态
 * @property string $chain 链
 * @property string $contract 合约
 */
class UserWithdraw extends BaseModel
{
    use HasDateTimeFormatter;

    protected $table = 'user_withdraws';
    protected $guarded = [];


    public static function fee($amount, $rate = 0)
    {
        $rate = g_rate_multi($rate);
        return asMoney($amount * $rate, 4);
    }

    public function withdraw($data)
    {
        $amount = $data['from_amount'];
        $user_asset = UserAsset::getContractAccount($data['uid']);

        if ($user_asset->balance < $amount) {
            throw new ApiException("余额不足");
        }

        $user = User::getUserOuter($data['uid']);
        if (!Hash::check($data['pay_pwd'], $user->pay_password)) {
            throw new ApiException('密码错误');
        }

        try {

            $rate = g_rate_multi(GlobalConfigService::get('withdraw.rate', 0.01));
            DB::beginTransaction();
            $fee = self::fee($amount, $rate);
            $from_symbol = "USD";
            $this->uid = $data['uid'];
            $this->from_symbol = $from_symbol;
            $this->from_amount = $amount;
            $this->to_symbol = "USDT";
            $this->to_amount = $amount;
            $this->rate = $rate;
            $this->from_address = "";
            $this->to_address = $data['address'];
            $this->status = WITHDRAW_COMMIT;
            $this->fee_symbol = "USD";
            $this->fee = $fee;
            $this->remark = "";
            $this->real_amount = $amount - $fee;
            $this->executed_tx = "";
            $this->created_at = date("Y-m-d H:i:s", time());
            $this->updated_at = date("Y-m-d H:i:s", time());
            $this->save();

            $res = $user_asset->assetChange($data['uid'], "USD", -$amount, ASSET_WITHDRAW, $this->id);
            if (!$res) {
                throw new ApiException("余额不足");
            }

            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            HelpService::forceLog($e);
            if ($e->getCode() == DEFAULT_CODE) {
                throw new ApiException($e->getMessage());
            } else {
                throw new ApiException("提交失败请稍后再试");
            }
        }

        return false;
    }

    /**
     * @param $uid
     * @param $amount
     * @param $remark
     * @return void
     */
    public static function withdrawSYS($uid, $amount, $remark)
    {
        return DB::transaction(function () use ($uid, $amount, $remark) {
            $rate = g_rate_multi(0);
            $model_withdraw = self::query()->create([
                "uid" => $uid,
                "from_symbol" => ASSET_SYMBOL_DEFAULT,
                "from_amount" => $amount,
                "to_symbol" => ASSET_SYMBOL_DEFAULT,
                "to_amount" => $amount,
                "rate" => $rate,
                "from_address" => "uid:{$uid}",
                "to_address" => "SYSTEM",
                "status" => WITHDRAW_SUCCESS,
                "fee_symbol" => ASSET_SYMBOL_DEFAULT,
                "fee" => self::fee($amount, $rate),
                "remark" => $remark,
                "executed_at" => now(),
                "created_at" => now(),
            ]);

            (new UserAsset())->assetChange(
                $uid,
                ASSET_SYMBOL_DEFAULT,
                -$amount,
                ASSET_WITHDRAW_SYS,
                $model_withdraw->id
            );

            return true;
        });
    }

    public function history($params)
    {
        $result = self::list("*", ['uid' => $params['uid']], $params);
        foreach ($result['list'] as &$v) {

        }
        return $result;
    }

    public function success()
    {
        try {
            DB::beginTransaction();
            $this->update(['status' => WITHDRAW_SUCCESS]);
            DB::commit();
            return true;

        } catch (\Exception $e) {
            HelpService::forceLog($e);
            DB::rollBack();
        }
        return false;
    }


    public function fail()
    {
        try {
            DB::beginTransaction();
            $this->update(['status' => WITHDRAW_FAIL]);
            /**
             * @var $user_asset TgChannelBalance
             */
            $user_asset = TgChannelBalance::query()->where('channel_id', $this->uid)->first();
            $user_asset->assetChange(
                $this->uid,
                ASSET_SYMBOL_DEFAULT,
                $this->to_amount,
                ASSET_WITHDRAW_BACK,
                $this->id
            );

            DB::commit();
            return true;

        } catch (\Exception $e) {
            HelpService::forceLog($e);
            DB::rollBack();
        }
        return false;
    }

    public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(User::class, 'uid', 'id');
    }

}
